<template>
  <div>
    <!--面包屑导航-->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>角色列表</el-breadcrumb-item>
    </el-breadcrumb>
    <!--卡片视图-->
    <el-card>
      <!--添加角色按钮-->
      <el-row>
        <el-col :span="3">
          <el-button type="primary" @click="addRoleVisible = true">添加角色</el-button>
        </el-col>
      </el-row>
      <!--角色列表-->
      <el-table :data="rolesList" border>
        <!--可展开列-->
        <el-table-column type="expand">
          <template slot-scope="scope">
            <el-row v-for="(item1, i1) in scope.row.children" :key="item1.id" :class="['border_bottom_1', i1 === 0 ?'border_top_1':'']">
              <!--一级权限-->
              <el-col :span="5">
                <el-tag closable @close="removeRightById(scope.row,item1.id)">{{item1.authName}}</el-tag>
                <i class="el-icon-caret-right"></i>
              </el-col>
              <!--二级权限和三级权限-->
              <el-col :span="19">
                <el-row v-for="(item2, i2) in item1.children" :key="item2.id" :class="[i2 !== 0 ?'border_top_1':'']">
                  <el-col :span="6">
                    <el-tag type="success" closable @close="removeRightById(scope.row,item2.id)">{{item2.authName}}</el-tag>
                    <i class="el-icon-caret-right"/>
                  </el-col>
                  <el-col :span="18">
                    <el-tag v-for="(item3) in item2.children" type="warning" :key="item3.id"
                            closable @close="removeRightById(scope.row,item3.id)">{{item3.authName}}</el-tag>
                  </el-col>
                </el-row>
              </el-col>
            </el-row>
          </template>
        </el-table-column>
        <el-table-column label="角色名称" prop="roleName"></el-table-column>
        <el-table-column label="角色描述" prop="roleDesc"></el-table-column>
        <el-table-column label="操作">
          <template slot-scope="scope">
            <el-button size="small" type="primary" icon="el-icon-edit" @click="showEditRoleDialog(scope.row.id)"></el-button>
            <el-button size="small" type="danger" icon="el-icon-delete" @click="deleteRoleById(scope.row.id)"></el-button>
            <el-button size="small" type="warning" icon="el-icon-setting" @click="showSetRightsDialog(scope.row)"></el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
    <!--用于添加角色的弹出框-->
    <el-dialog :visible.sync="addRoleVisible" title="添加角色" width="400px" @close="addRoleDialogClosed">
      <el-form :model="addRoleForm" :rules="addRoleRules" ref="addRoleRef" label-width="90px">
        <el-form-item label="角色名称" prop="roleName">
          <el-input v-model="addRoleForm.roleName"/>
        </el-form-item>
        <el-form-item label="角色描述" prop="roleDesc">
          <el-input v-model="addRoleForm.roleDesc"/>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="addRoleVisible = false">取 消</el-button>
        <el-button type="primary" @click="saveAddRole">确 定</el-button>
      </div>
    </el-dialog>
    <!--用于修改角色的弹出框-->
    <el-dialog width="400px" :visible.sync="editDialogFormVisible" title="修改角色" @close="editRoleDialogClosed">
      <el-form :model="editRoleForm" label-width="90px" :rules="addRoleRules" ref="editRoleRef">
        <el-form-item label="角色名称" prop="roleName">
          <el-input v-model="editRoleForm.roleName"/>
        </el-form-item>
        <el-form-item label="角色描述" prop="roleDesc">
          <el-input v-model="editRoleForm.roleDesc"/>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="editDialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="editRoleById">确 定</el-button>
      </div>
    </el-dialog>
    <!--用于修改角色下的权限，通过多选框来添加或删除权限 树形结构 弹出框-->
    <el-dialog width="600px" :visible.sync="treeDialogFormVisible" title="修改角色" @close="treeDialogClosed">
      <el-tree :data="treeData" node-key="id" :props="treeProps" default-expand-all show-checkbox :default-checked-keys='defaultCheckedIds' ref="treeRef">
      </el-tree>
      <div slot="footer" class="dialog-footer">
        <el-button @click="treeDialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="saveRightsForRoleByIds">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
export default {
  data () {
    return {
      rolesList: [],
      addRoleForm: {},
      editRoleForm: {},
      addRoleRules: {
        roleName: [
          { required: true, message: '请输入角色名称', trigger: 'blur' },
          {
            min: 2,
            max: 10,
            message: '角色名称的长度在2～10个字',
            trigger: 'blur'
          }
        ]
      },
      treeData: {},
      treeProps: {
        label: 'authName',
        children: 'children'
      },
      defaultCheckedIds: [],
      currentRoleId: '',
      addRoleVisible: false,
      treeDialogFormVisible: false,
      editDialogFormVisible: false
    }
  },
  created () {
    this.getRolesList()
  },
  methods: {
    /* 获取角色列表以及角色下的权限 */
    async getRolesList () {
      const { data: res } = await this.$http.get('roles')
      if (res.meta.status === 200) {
        this.rolesList = res.data
      } else this.$message.error('角色列表获取失败')
    },
    /* 删除某个角色下的某个权限 */
    async removeRightById (row, rightId) {
      const confirmResult = await this.$confirm('是否确认删除当前角色的该权限？', '提示',
        {
          confirmButtonText: '确认',
          cancelButtonText: '取消',
          type: 'success'
        }
      ).catch(err => err)
      if (confirmResult !== 'confirm') return this.$message.info('已取消删除')
      const { data: res } = await this.$http.delete(`roles/${row.id}/rights/${rightId}`)
      if (res.meta.status === 200) {
        this.$message.success('权限删除成功')
        row.children = res.data
      } else this.$message.err('权限删除失败')
    },
    /* 监听添加觉得弹出框，关闭弹出框重置里面的表单 */
    addRoleDialogClosed () {
      this.addRoleVisible = false
      this.$refs.addRoleRef.resetFields()
    },
    /* 添加角色的请求 */
    saveAddRole () {
      this.$refs.addRoleRef.validate(async vali => {
        if (vali) {
          const { data: res } = await this.$http.post('roles', this.addRoleForm)
          if (res.meta.status === 201) {
            this.addRoleVisible = false
            this.$message.success('添加角色成功')
            this.getRolesList()
          } else this.$message.error('添加角色失败')
        }
      })
    },
    /* 根据id获取角色信息，用于修改 */
    async showEditRoleDialog (roleId) {
      const { data: res } = await this.$http.get('roles/' + roleId)
      if (res.meta.status === 200) {
        this.editRoleForm = res.data
        this.editDialogFormVisible = true
      } else this.$message.error('无法根据该ID获取角色')
    },
    /* 修改角色的请求 */
    editRoleById () {
      this.$refs.editRoleRef.validate(async vali => {
        if (vali) {
          console.log(this.editRoleForm)
          const { data: res } = await this.$http.put('roles/' + this.editRoleForm.roleId, {
            roleName: this.editRoleForm.roleName,
            roleDesc: this.editRoleForm.roleDesc
          })
          console.log(res)
          if (res.meta.status === 200) {
            this.editDialogFormVisible = false
            this.$message.success('修改角色成功')
            this.getRolesList()
          } else this.$message.error('修改角色失败')
        }
      })
    },
    editRoleDialogClosed () {
      this.editDialogFormVisible = false
      this.$refs.editRoleRef.resetFields()
    },
    /* 根据ID删除角色 */
    async deleteRoleById (roleId) {
      const confirmResult = await this.$confirm('是否删除该角色', '删除角色', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        /* 该type主要切换提示语开头的图标 */
        type: 'warning'
      }).catch(err => err)
      if (confirmResult !== 'confirm') return this.$message.info('已取消删除')
      else {
        const { data: res } = await this.$http.delete('roles/' + roleId)
        if (res.meta.status === 200) {
          this.$message.success('删除角色成功')
          this.getRolesList()
        } else this.$message.success('删除角色失败：' + res.meta.msg)
      }
    },
    /* 显示树形权限列表的弹出框 */
    async showSetRightsDialog (role) {
      this.currentRoleId = role.id
      /* 查询所有树形权限列表 tree */
      const { data: res } = await this.$http.get('rights/tree')
      if (res.meta.status === 200) {
        /* 获取所有该角色已经有的三级权限 */
        this.getCheckedRights(role, this.defaultCheckedIds)
        this.treeData = res.data
        this.treeDialogFormVisible = true
      } else return this.$message.error('获取树形权限列表失败')
    },
    /* 监听树形弹出框关闭事件 */
    treeDialogClosed () {
      this.defaultCheckedIds = []
      this.currentRoleId = ''
    },
    getCheckedRights (role, arr) {
      if (!role.children) arr.push(role.id)
      else {
        role.children.forEach(item => {
          this.getCheckedRights(item, arr)
        })
      }
    },
    async saveRightsForRoleByIds () {
      const checkedKeys = [...this.$refs.treeRef.getCheckedKeys(), ...this.$refs.treeRef.getHalfCheckedKeys()]
      const keysStr = checkedKeys.join(',')
      const { data: res } = await this.$http.post(`roles/${this.currentRoleId}/rights`, {
        rids: keysStr
      })
      if (res.meta.status === 200) {
        this.$message.success('修改成功')
        this.treeDialogFormVisible = false
        this.getRolesList()
      } else this.$message.error('修改失败')
    }
  }
}
</script>

<style lang="less" scoped>
  .el-tag{
    margin: 7px 0 7px 7px;
  }
  .el-card .el-row{
    display: flex;
    align-items: center;
  }
</style>
